layui.define(['table', 'jquery', 'util', 'layer', 'dropdown', 'layuiFastHelper'], function (exports) {
    "use strict";

    let table = layui.table;
    let $ = layui.jquery;
    let dropdown = layui.dropdown;
    let layuiFastHelper = layui.layuiFastHelper;

    // 表格组件
    var layuiFastTable = {
        defaults: {
            pk: 'id', // 列表数据主键
            search: true, // 是否开启搜索
            page: true, // 分页
            limits: [10, 50, 100, 500, 1000], // 每页条数的选择项
            request: {
                pageName: 'page',
                offsetName: 'offset',
                limitName: 'limit',
                sortName: 'sort',
                orderName: 'order',
            },
            parseData: function (data) {
                return {
                    code: data.code,
                    msg: data.msg,
                    count: data.data.total,
                    data: data.data.rows,
                };
            },
            skin: 'line', // 表格样式
            even: false,
            autoSort: false, // 关闭前端排序
            initSort: {
                field: '', // 按字段排序
                type: 'desc' // 降序排序
            },
            before: function (options) {
                // 增加offset分页参数
                options.where[options.request.offsetName] = (options.page.curr || 1) * options.limit;
                // 默认用主键排序
                options.initSort.field = options.initSort.field || options.pk;
                // 处理排序
                if (options.initSort.type) {
                    options.where[options.request.sortName] = options.initSort.field;
                    options.where[options.request.orderName] = options.initSort.type;
                } else {
                    delete options.where[options.request.sortName];
                    delete options.where[options.request.orderName];
                }
            },
            size: 'md', // 表格大小
            toolbar: [ // 左边工具栏
                {
                    title: '刷新',
                    text: '',
                    layEvent: 'refresh',
                    icon: 'layui-icon-refresh',
                    class: 'layui-btn-primary btn-refresh'
                },
                {title: '添加', text: '', layEvent: 'add', icon: 'layui-icon-add-1', class: 'layui-btn-primary btn-add'},
                {
                    title: '编辑',
                    text: '',
                    layEvent: 'editMulti',
                    icon: 'layui-icon-edit',
                    class: 'layui-btn-primary btn-editMulti'
                },
                {
                    title: '删除',
                    text: '',
                    layEvent: 'deleteMulti',
                    icon: 'layui-icon-delete',
                    class: 'layui-btn-primary btn-deleteMulti'
                },
                {
                    title: '选择',
                    text: '',
                    layEvent: 'select',
                    icon: 'layui-icon layui-icon-ok',
                    class: 'layui-btn-primary btn-disabled'
                },
            ],
            toolbarEvents: {}, // 自定义工具栏按钮事件
            // 右边工具栏
            defaultToolbar: ['filter', 'print', 'exports'],
            urls: {
                index: '', // 列表接口URL
                detail: '', // 详情按钮URL
                edit: '', // 编辑按钮URL
                add: '', // 添加按钮URL
                del: '', // 删除按钮URL
                multi: '' // 批量操作按钮URL
            },
            done: function () {
            },
        },
        defaultEvents: {
            refresh: function (obj) {
                layuiFastTable.api.refresh(obj.config.id);
            },
            // 点击添加按钮事件处理
            add: function (obj) {
                layuiFastHelper.open('添加', obj.config.urls.add, {
                    callback: function (data) {
                        layuiFastTable.api.refresh(obj.config.id);
                    }
                })
            },
            // 点击批量编辑按钮事件处理
            editMulti: function (obj) {
                if ($(this).hasClass('layui-btn-disabled')) {
                    return;
                }
                var aCheckId = layuiFastTable.api.getCheckField(obj, obj.config.pk).split(',').filter(function (val) {
                    return val !== ''
                });
                if (aCheckId.length === 0) {
                    layuiFastHelper.msg('请选择操作的列', true);
                    return;
                }
                if (aCheckId > 20) {
                    layuiFastHelper.msg('最多同时编辑20个', true);
                    return;
                }
                for (i in aCheckId) {
                    var data = {};
                    data[obj.config.pk] = aCheckId[i];
                    layuiFastHelper.open('编辑', layuiFastTable.api.replaceurl(obj.config.urls.edit, data, obj.config), {
                        callback: function (data) {
                            layuiFastTable.api.refresh(obj.config.id);
                        }
                    })
                }
            },
            // 点击批量删除按钮事件处理
            deleteMulti: function (obj) {
                if ($(this).hasClass('layui-btn-disabled')) {
                    return;
                }
                var data = {};
                data[obj.config.pk] = layuiFastTable.api.getCheckField(obj, obj.config.pk);
                if (data[obj.config.pk] === '') {
                    layuiFastHelper.msg('请选择操作的列', true);
                    return;
                }
                layuiFastHelper.confirm('确定要删除！', function () {
                    layuiFastHelper.http('POST', obj.config.urls.del, data).then(function (res) {
                        layuiFastTable.api.refresh(obj.config.id)
                    });
                })
            },
            // 点击详情按钮事件处理
            detail: function (obj) {
                layuiFastHelper.open('详情', layuiFastTable.api.replaceurl(obj.config.urls.detail, obj.data, obj.config));
            },
            // 点击弹窗事件处理
            dialog: function () {
                var that = this;
                layuiFastHelper.open($(this).data('title') || $(this).attr('title') || $(this).text(), $(this).data('url'), {
                    callback: function (data) {
                        $('#' + $(that).data('input-id')).val(data).trigger("change");
                    }
                });
            },
            // 点击编辑按钮事件处理
            edit: function (obj) {
                layuiFastHelper.open('编辑', layuiFastTable.api.replaceurl(obj.config.urls.edit, obj.data, obj.config), {
                    callback: function (data) {
                        layuiFastTable.api.refresh(obj.config.id);
                    }
                });
            },
            // 点击删除按钮事件处理
            delete: function (obj) {
                layuiFastHelper.confirm('确定要删除！', function () {
                    var data = {};
                    data[obj.config.pk] = obj.data[obj.config.pk];
                    layuiFastHelper.http('POST', obj.config.urls.del, data).then(function (res) {
                        layuiFastTable.api.refresh(obj.config.id);
                    });
                })
            },
            // 批量操作按钮事件处理
            multi: function (obj) {
                if ($(this).hasClass('layui-btn-disabled')) {
                    return;
                }
                var data = layui.url('?' + $(this).data('params')).search;
                data[obj.config.pk] = layuiFastTable.api.getCheckField(obj, obj.config.pk);
                if (data[obj.config.pk] === '') {
                    layuiFastHelper.msg('请选择操作的列', true);
                    return;
                }
                var url = $(this).data('url') || obj.config.urls.multi;
                layuiFastHelper.confirm('确定要操作！', function () {
                    layuiFastHelper.http('POST', url, data).then(function (res) {
                        layuiFastTable.api.refresh(obj.config.id)
                    });
                })
            },
            // 选择按钮事件处理
            select: function (obj) {
                if ($(this).hasClass('layui-btn-disabled')) {
                    return;
                }
                layuiFastHelper.close(layuiFastTable.api.getCheckField(obj, obj.config.pk));
            },
            // 更多按钮事件处理
            more: function (obj) {
                var buttons = $(this).data('more-buttons');
                var data = [];
                for (let i = 0; i < buttons.length; i++) {
                    data.push({
                        text: buttons[i].text || buttons[i].title,
                        ...buttons[i],
                    })
                }
                dropdown.render({
                    elem: this, // 触发事件的 DOM 对象
                    show: true, // 外部事件触发即显示
                    templet: function (button) {
                        return layuiFastHelper.link([button]);
                    },
                    data: data,
                    click: function (menudata, $btn) {
                        obj.event = menudata.layEvent;
                        if ($($($btn.html()).html()).data('key')) {
                            layuiFastTable.api.event.tool.call($($($btn.html()).html()), obj);
                        } else {
                            layuiFastTable.api.event.toolbar.call($($($btn.html()).html()), obj);
                        }
                    },
                    align: 'right', // 右对齐弹出
                    style: 'box-shadow: 1px 1px 10px rgb(0 0 0 / 12%);' // 设置额外样式
                })
            }
        },
        api: {
            // 初始化
            init: function (opts) {
                opts.toolbar = opts.toolbar || [];
                for (let i = 0; i < opts.toolbar.length; i++) {
                    layuiFastTable.defaults.toolbar.push(opts.toolbar[i]);
                }
                var toolbars = layuiFastTable.defaults.toolbar;
                layuiFastTable.defaults.toolbar = [];
                var data = layui.url();
                for (let i = 0; i < toolbars.length; i++) {
                    var toolbar = toolbars[i];
                    // 处理URL中isSelectDialog参数表示选择弹窗
                    if (data.search.isSelectDialog == 1 && (toolbar.layEvent != 'refresh' && toolbar.layEvent != 'select')) {
                        continue;
                    } else if (data.search.isSelectDialog != 1 && toolbar.layEvent == 'select') {
                        continue;
                    }
                    layuiFastTable.defaults.toolbar.push(toolbar);
                }
                opts.toolbar = layuiFastHelper.toolbar(layuiFastTable.defaults.toolbar);
                $.extend(true, layuiFastTable.defaults, opts)
            },
            open: function (title, url) {
                return layuiFastHelper.open(title, url);
            },
            render: function (opts) {
                var thisTable = table.render($.extend({}, layuiFastTable.defaults, opts));
                layuiFastTable.api.bindevent(thisTable.config.id);
                if (thisTable.config.search) {
                    layui.use(['layuiFastTableSearch'], function () {
                        layui.layuiFastTableSearch.api.render(thisTable.config.id, layuiFastTable.api.getFieldByCols(thisTable.config.cols))
                    });
                }
                return thisTable;
            },
            // 刷新
            refresh: function (id, opts) {
                table.reload(id, $.extend({}, opts));
            },
            on: table.on,
            event: {
                // 表头工具栏操作按钮事件
                toolbar: function (obj) {
                    // 通用的事件
                    layuiFastTable.defaultEvents[obj.event] && layuiFastTable.defaultEvents[obj.event].call(this, obj);
                    // 自定义的事件
                    if (obj.config.toolbarEvents && obj.config.toolbarEvents[obj.event]) {
                        obj.config.toolbarEvents[obj.event].call(this, obj);
                    }
                    return true;
                },
                // 单元格操作按钮事件
                tool: function (obj) {
                    var key = $(this).data('key').split('-');
                    var col = obj.config.cols[key[1]][key[2]];
                    // 通用的事件
                    layuiFastTable.defaultEvents[obj.event] && layuiFastTable.defaultEvents[obj.event].call(this, obj);
                    // 自定义的事件
                    if (col.buttonEvents && col.buttonEvents[obj.event]) {
                         col.buttonEvents[obj.event].call(this, obj);
                    }
                },
                // 多选框按钮事件
                checkbox: function (obj) {
                    if (table.checkStatus(obj.config.id).data.length > 0) {
                        $('[lay-id="' + obj.config.id + '"]').find('.toolbar').find('.btn-disabled').removeClass('layui-btn-disabled')
                    } else {
                        $('[lay-id="' + obj.config.id + '"]').find('.toolbar').find('.btn-disabled').addClass('layui-btn-disabled')
                    }
                },
                sort: function (obj) {
                    layuiFastTable.api.refresh(obj.config.id, {
                        initSort: obj,
                    });
                },
            },
            bindevent: function (id) {
                // 表头工具栏事件
                table.on('toolbar(' + id + ')', layuiFastTable.api.event.toolbar);
                // 单元格操作事件
                table.on('tool(' + id + ')', layuiFastTable.api.event.tool);
                // 表格多选框事件
                table.on('checkbox(' + id + ')', layuiFastTable.api.event.checkbox);
                // 排序事件
                table.on('sort(' + id + ')', layuiFastTable.api.event.sort);
            },
            // 通用单元格格式化模版
            templet: {
                // 徽章格式化
                badge: function (row) {
                    var searchData = this.searchData !== undefined ? this.searchData : [];
                    var value = searchData[row[this.field]] !== undefined ? searchData[row[this.field]] : row[this.field];
                    var colors = [
                        // 橙,绿,青,蓝,深,浅
                        'orange', 'green', 'cyan', 'blue', 'black', 'gray',
                    ];
                    return '<span class="layui-badge layui-bg-' + colors[row[this.field]] + '">' + (value === undefined ? '-' : value) + '</span>'
                },
                // 状态格式化
                status: function (row) {
                    var searchData = this.searchData !== undefined ? this.searchData : [];
                    var value = searchData[row[this.field]] !== undefined ? searchData[row[this.field]] : row[this.field];
                    var colors = [
                        // 橙,绿,青,蓝,深,浅
                        'orange', 'green', 'cyan', 'blue', 'black', 'gray',
                    ];
                    return '<span class="layui-badge-dot layui-bg-' + colors[row[this.field]] + '"></span>' + ' ' + (value === undefined ? '-' : value);
                },
                // 时间格式化
                datetime: function (row) {
                    if (row[this.field] === undefined) {
                        return '';
                    }
                    var datetimeFormat = typeof this.datetimeFormat === 'undefined' ? 'yyyy-MM-dd HH:mm:ss' : this.datetimeFormat;
                    return layui.util.toDateString(row[this.field], datetimeFormat);
                },
                // 操作按钮格式化
                operate: function (row, obj) {
                    var buttons = [];
                    var urls = obj.config.urls;
                    var that = this;
                    // 通用操作按钮
                    urls.detail != '' && buttons.push({
                        name: 'detail',
                        title: '详情',
                        layEvent: 'detail',
                        icon: 'layui-icon-form',
                        class: 'layui-btn-primary btn-detail',
                    });
                    urls.edit != '' && buttons.push({
                        name: 'edit',
                        title: '编辑',
                        layEvent: 'edit',
                        icon: 'layui-icon-edit',
                        class: 'layui-btn-primary btn-edit',

                    });
                    urls.delete != '' && buttons.push({
                        name: 'delete',
                        title: '删除',
                        layEvent: 'delete',
                        icon: 'layui-icon-delete',
                        class: 'layui-btn-primary btn-delete'
                    });
                    // 自定义操作按钮
                    this.buttons = this.buttons || [];
                    buttons = [...buttons, ...this.buttons];
                    buttons = buttons.filter(function (button) {
                        if (typeof that.buttonHandle !== 'function') {
                            return true;
                        }
                        return !(that.buttonHandle.call(that, button, row, obj) === false);
                    });
                    var key = row.LAY_COL.key;
                    var field = key.split('-')[2];
                    for (let i = 0; i < buttons.length; i++) {
                        var button = buttons[i];
                        button.extend = (button.extend || '') + ' data-key="' + key + '" data-field="' + field + '"';
                    }
                    if (buttons.length > 3) {
                        buttons = [
                            buttons[0],
                            buttons[1],
                            {
                                name: 'more',
                                title: '更多',
                                layEvent: 'more',
                                icon: 'layui-icon-down',
                                class: 'layui-btn-primary btn-more',
                                extend: [
                                    "data-more-buttons='" + JSON.stringify(buttons.slice(2)) + "'",
                                    'data-key="' + key + '"',
                                    'data-field="' + field + '"',
                                ].join(' '),
                            }
                        ]
                    }
                    for (let i = 0; i < buttons.length; i++) {
                        var button = buttons[i];
                        if (obj.config.size === 'sm') {
                            button.class = button.class + ' layui-btn-xs';
                        }
                    }
                    return layuiFastHelper.buttonGroup(buttons);
                }
            },
            // 替换url花括号占位符
            replaceurl: function (url, data, config) {
                var pk = config.pk;
                url = !url.match("/\{" + pk + "\}/i") ? url + (url.match(/(\?|&)+/) ? "&" + pk + "=" : "?" + pk + "=") + "{" + pk + "}" : url;
                url = url.replace(/\{(.*?)\}/gi, function (matched) {
                    matched = matched.substring(1, matched.length - 1);
                    if (matched.indexOf(".") !== -1) {
                        var temp = data;
                        var arr = matched.split(/\./);
                        for (var i = 0; i < arr.length; i++) {
                            if (typeof temp[arr[i]] !== 'undefined') {
                                temp = temp[arr[i]];
                            }
                        }
                        return typeof temp === 'object' ? '' : temp;
                    }
                    return data[matched];
                });
                return url;
            },
            // 获取列表中的字段
            getFieldByCols: function (cols) {
                var fields = [];
                for (let i = 0; i < cols.length; i++) {
                    var col = cols[i];
                    if (Array.isArray(col) === true) {
                        return layuiFastTable.api.getFieldByCols(col);
                    }
                    if (col['field']) {
                        fields.push(col);
                    }
                }
                return fields;
            },
            getCheckField: function (obj, field) {
                let rows = table.checkStatus(obj.config.id).data;
                if (rows.length === 0) {
                    return '';
                }
                let data = [];
                for (let i = 0; i < rows.length; i++) {
                    data.push(rows[i][field]);
                }
                return data.join(',');
            }
        }
    }
    exports('layuiFastTable', layuiFastTable)
});